﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Collections.ObjectModel;


namespace CitrixPVSWrapper
{
    public static partial class PvsHelpers 
    {

        public static MCliReturnObject ExecuteMcliAction (QueryDefinition Query, Boolean Verbose = false, Boolean Debug = false)
        {
            if (Verbose) { Console.WriteLine("VERBOSE: Executing MCli " + Query.Action + ". Verbose mode enabled"); }

            // Set up the PowerShell session and include the snapin required
            RunspaceConfiguration runConfig = RunspaceConfiguration.Create();
            PSSnapInException psEx = null;
            runConfig.AddPSSnapIn("mclipssnapin", out psEx);
            Runspace runspace = RunspaceFactory.CreateRunspace(runConfig);
            runspace.Open();

            // Execute all of the queries
            if (Verbose) {
                    Console.WriteLine("VERBOSE: Target Object is: " + Query.TargetObject.ToString());
                    Console.WriteLine("VERBOSE: Parameters: " + String.Join(", ", Query.Parameters));
                    Console.WriteLine("VERBOSE: Record Values: " + String.Join(", ", Query.RecordValues));
            }

            // Build the query up from the provided parameters
            string QueryScript = "";
            switch (Query.Action)
            {
                case QueryActionType.Set:
                    QueryScript = "mcli-set"; break;
                case QueryActionType.SetList:
                    QueryScript = "mcli-setlist"; break;
                case QueryActionType.Add: 
                    QueryScript = "mcli-add"; break;
                case QueryActionType.Remove:
                    QueryScript = "mcli-delete"; break;
                case QueryActionType.Run:
                    QueryScript = "mcli-run"; break;
            }
            QueryScript += " -Type " + Query.TargetObject;
            if (Query.Parameters.Count > 0) { QueryScript += " -p " + String.Join(",", Query.Parameters); }
            if (Query.RecordValues.Count > 0) { QueryScript += " -r " + String.Join(",", Query.RecordValues); }
            QueryScript += " -ErrorAction Stop";
            if (Verbose) { Console.WriteLine("VERBOSE: Command to execute: " + QueryScript); }

            Pipeline pipeline = runspace.CreatePipeline();
            pipeline.Commands.AddScript(QueryScript);

            // Run the query, and collect the results
            List<string> QueryResults = pipeline.Invoke().Select(r => r.ToString()).ToList();   
            if (Verbose) { Console.WriteLine("VERBOSE: Query executed. Lines in result: " + QueryResults.Count()); }
            
            // Convert the String Errors to ErrorRecords - simplifies later processing
            Collection<ErrorRecord> ErrorRecords = new Collection<ErrorRecord>();
            foreach (String Error in pipeline.Error.ReadToEnd().Select(n => n.ToString()).ToList()) 
            { ErrorRecords.Add(new ErrorRecord(new PSSnapInException(Error), "-2", System.Management.Automation.ErrorCategory.SyntaxError, null)); }
            if (Verbose) { Console.WriteLine("VERBOSE: Query executed. Errors: " + ErrorRecords.Count()); }

            // Tidy up the Powershell session
            runspace.Close();
            if (Verbose) { Console.WriteLine("VERBOSE: All queries complete. Total lines in output: " + QueryResults.Count); }

            return new MCliReturnObject(ReturnState.Success,ErrorRecords);
        }
    
    }

}
